package com.whoisaa.wifitransfer;

import android.content.Context;
import android.os.Handler;

import com.whoisaa.wifitransfer.base.BaseThread;
import com.whoisaa.wifitransfer.bean.ConnectedInfo;
import com.whoisaa.wifitransfer.bean.FileInfo;
import com.whoisaa.wifitransfer.bean.Header;
import com.whoisaa.wifitransfer.utils.L;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description 发送端线程
 * @Author AA
 * @DateTime 16/4/19 下午5:33
 */
public class WifiServerThread extends BaseThread {

    private Context mContext;
    private Handler mHandler;
    private Header mHeader;

    private List<ConnectedInfo> mConnectedInfos = new ArrayList<>();
    private ServerSocket mServerSocket;
    private Socket mSocket;
    private IServerConnectionListener mConnectionListener;

    private boolean isRun = true;


    public WifiServerThread(Context context, Header header, Handler handler, IServerConnectionListener listener) {
        this.mContext = context;
        this.mHeader = header;
        this.mHandler = handler;
        this.mConnectionListener = listener;
    }

    @Override
    public void run() {
        try {
            if(mServerSocket == null) {
                mServerSocket = new ServerSocket(SERVERPOST);
            }
            while (isRun) {
                mSocket = mServerSocket.accept();
                if(mSocket != null && mConnectionListener != null) {
                    //保持连接
                    mSocket.setKeepAlive(true);
                    String ipAddress = mSocket.getInetAddress().getHostAddress();
                    if(!isExist(mConnectedInfos, mSocket)) {
                        InputStream is = mSocket.getInputStream();
                        byte[] data = new byte[buf_size];
                        int len = is.read(data);
                        String mobileModel = new String(data, 0, len);
                        mobileModel = mobileModel == null ? "" : (mobileModel + " : ");
//                        is.close();

                        ConnectedInfo connectedInfo = new ConnectedInfo(mSocket, ipAddress, mobileModel);
                        mConnectedInfos.add(connectedInfo);
                    }
                    mConnectionListener.onSuccess(mConnectedInfos);
                    L.error("Socket连接成功: " + ipAddress);
                    sendMessage(mHandler, 10, "Socket连接成功: " + ipAddress);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            if(mHandler != null) {
                sendMessage(mHandler, 10, "创建失败: " + e.getMessage());
            }
        }
    }

    /**
     * 避免重复添加
     * @param connectedInfos
     * @param curSocket
     * @return
     */
    private boolean isExist(List<ConnectedInfo> connectedInfos, Socket curSocket) {
        for(ConnectedInfo connectedInfo : connectedInfos) {
           if(connectedInfo.getIpAddress().equals(curSocket.getInetAddress().getHostAddress())) {
               return true;
           }
        }
        return false;
    }

    /**
     * 发送
     * @return
     */
    public void send() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OutputStream outputStream = mSocket.getOutputStream();
                    InputStream inputStream = mSocket.getInputStream();

                    //将文件名和文件大小发送给接收端
                    outputStream.write(getHeaderString(mHeader).getBytes(UTF_8));
                    outputStream.flush();
                    sendMessage(mHandler, 10, "已发送文件名和文件大小");

                    byte[] startData = new byte[buf_size];
                    int len = inputStream.read(startData);
                    if(len != -1) {
                        String start = new String(startData, 0, len);
                        if(start.equals("start")) {
                            for(FileInfo fileInfo : mHeader.getFileInfos()) {
                                int sentLen = 0;
                                byte[] sendData = new byte[file_buf_size];
                                long totalSize = fileInfo.getFileLength();
                                InputStream fileInputStream = new FileInputStream(new File(fileInfo.getFileName()));
                                sendMessage(mHandler, 10, "正在发送: " + fileInfo.getFileName());
                                while ((len = fileInputStream.read(sendData)) != -1) {
                                    outputStream.write(sendData, 0, len);
                                    sentLen += len;
                                    int progress = (int) (sentLen * 100 / totalSize);
                                    L.error("文件(" + fileInfo.getFileName() + ") 总大小: " + totalSize + " 已接收文件(" + progress + "): " + sentLen);
                                }
                                fileInputStream.close();
                            }
                            outputStream.close();
                        }
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    L.error("FileNotFoundException: " + e.getMessage());
                } catch (IOException e) {
                    e.printStackTrace();
                    L.error("IOException: " + e.getMessage());
                } finally {
                    try {
                        mSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    sendMessage(mHandler, 10, "发送完成");
                }
            }
        }).start();
    }

    /**
     * 获得文件头部信息的字符串
     * @param header
     * @return
     */
    private String getHeaderString(Header header) {
        StringBuilder sb = new StringBuilder();
        //手机型号
        sb.append(header.getMobileModel()).append(Header.separator);
        //文件总数
        sb.append(header.getFileTotalCount()).append(Header.separator);
        //文件名::文件大小
        for(FileInfo fileInfo : header.getFileInfos()) {
            String fileName = fileInfo.getFileName().substring(fileInfo.getFileName().lastIndexOf("/") + 1);
            sb.append(fileName).append(Header.file_separator).append(fileInfo.getFileLength()).append(Header.file_separator2);
        }
        return sb.toString();
    }


}
